package com.apes.framework.query;

import com.alibaba.druid.pool.DruidDataSource;
import com.apes.framework.query.lib.JPASqlCallBack;
import com.apes.framework.util.ClassPathScanUtil;
import com.apes.framework.util.ReflectUtil;
import com.apestech.api.file.listener.FileListener;
import com.apestech.api.xml.esb.EsbUtil;
import com.apestech.framework.util.DBUtil;
import com.apestech.framework.util.LocalVariable;
import com.apestech.framework.xml.XmlSysConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.Document;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.File;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;

@Component
public class QueryInitializingService implements InitializingBean {
    protected final Logger logger = LogManager.getLogger(this.getClass());
    @Autowired
    private MongoTemplate mongoTemplate;

    private DruidDataSource druidDataSource;

    public QueryInitializingService(DataSource dataSource) {
        if (dataSource instanceof DruidDataSource) {
            druidDataSource = (DruidDataSource) dataSource;
        } else {
            druidDataSource = (DruidDataSource) ReflectUtil.getPrivateField(dataSource, "realDataSource");
        }
    }

    @Override
    public void afterPropertiesSet() {
        try {
            LocalVariable.getSysQuery().setSqlCallback("esbjpa", new JPASqlCallBack());
            LocalVariable.setDefaultDir(ClassPathScanUtil.getConfigFilePath());
            XmlSysConfig config=LocalVariable.getConfig();
            String dbname = DBUtil.addDataSource(druidDataSource);
            DBUtil.setSysSingleDB("ESB", dbname);

            Executors.newCachedThreadPool().execute(new FileListener(LocalVariable.getRootDir()) {
                @Override
                public void execute(WatchKey watchKey, WatchEvent event) {
                    String file = watchKey.watchable().toString() + File.separator + event.context().toString();
                    int len = file.length();
                    if ("~".equals(file.substring(len - 1, len))) {
                        file = file.substring(0, len - 1);
                    }
                    try {
                        LocalVariable.getConfig().removeXmlFile(file);
                        EsbUtil.reloadFormXml(file);
                    } catch (Exception e) {
                        logger.error(e);
                    }
                }
            });
        } catch (Exception e) {
            saveLog(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    private void saveLog(String remark) {
        Document document = new Document();
        document.put("remark", remark);
        document.put("date", LocalDateTime.now());
        mongoTemplate.getCollection("tcConnection").insertOne(document);
    }
}
